package com.projx.accounting.module;

import jakarta.persistence.*;

import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

@Entity
@Table(name = "users")
public class User {
    @Id
    @Column(length = 36)
    private String id;

    @Column(nullable = false, unique = true)
    private String username;

    private String email;

    private String password;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"))
    @Column(name = "role")
    private Set<String> roles = new HashSet<>();

    private OffsetDateTime createdAt;

    private boolean active = true;

    @Transient
    private Map<String, Object> metadata = new HashMap<>();

    @PrePersist
    public void prePersist() {
        if (this.id == null) this.id = UUID.randomUUID().toString();
        if (this.createdAt == null) this.createdAt = OffsetDateTime.now();
    }

    public User() {
        this.roles = new HashSet<>();
        this.metadata = new HashMap<>();
        this.active = true;
    }

    public User(String id, String username, String email, String password, Set<String> roles, OffsetDateTime createdAt, boolean active, Map<String, Object> metadata) {
        this.id = id;
        this.username = username;
        this.email = email;
        this.password = password;
        this.roles = roles == null ? new HashSet<>() : roles;
        this.createdAt = createdAt;
        this.active = active;
        this.metadata = metadata == null ? new HashMap<>() : metadata;
    }

    public static User create(String username, String email) {
        User u = new User();
        u.id = UUID.randomUUID().toString();
        u.username = username;
        u.email = email;
        u.createdAt = OffsetDateTime.now();
        u.active = true;
        return u;
    }

    // getters/setters
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public Set<String> getRoles() { return roles; }
    public void setRoles(Set<String> roles) { this.roles = roles; }
    public OffsetDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(OffsetDateTime createdAt) { this.createdAt = createdAt; }
    public boolean isActive() { return active; }
    public void setActive(boolean active) { this.active = active; }
    public Map<String, Object> getMetadata() { return metadata; }
    public void setMetadata(Map<String, Object> metadata) { this.metadata = metadata; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return Objects.equals(id, user.id);
    }

    @Override
    public int hashCode() { return Objects.hash(id); }

    @Override
    public String toString() { return "User{" + "id='" + id + '\'' + ", username='" + username + '\'' + '}'; }
}
